package com.base.cn.platform.os.controller.statistics.users;

import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.statistics.base.StatisticsDateQueryCondition;
import com.base.cn.platform.os.entity.statistics.base.ZStatisticsOrderBaseCount;
import com.base.cn.platform.os.entity.statistics.ua.ZStatisticsActiveUserCount;
import com.base.cn.platform.os.entity.statistics.users.UserCountEntity;
import com.base.cn.platform.os.entity.statistics.users.UserRegFromEntity;
import com.base.cn.platform.os.entity.statistics.users.ZStatisticsPayUserCount;
import com.base.cn.platform.os.service.order.order.OrderBiz;
import com.base.cn.platform.os.service.statistics.ua.ZStatisticsActiveUserCountBiz;
import com.base.cn.platform.os.service.statistics.users.ZStatisticsPayUserCountBiz;
import com.base.cn.platform.os.service.user.user.CusUserBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户统计Controller
 *
 * @author s.li
 * @date 2019/04/30
 */
@RestController
@RequestMapping("/manage/statistics")
public class UsersStatisticsController {

    @Autowired
    private CusUserBiz cusUserBiz;
    @Autowired
    private ZStatisticsActiveUserCountBiz zStatisticsActiveUserCountBiz;
    @Autowired
    private OrderBiz orderBiz;
    @Autowired
    private ZStatisticsPayUserCountBiz zStatisticsPayUserCountBiz;

    /**
     * 用户趋势看板数据
     * @param dateQueryCondition 查询时间条件
     * @return Map<String,Object>
     */
    @RequestMapping("/queryUserTrendBoard")
    public Map<String,Object> queryUserTrendBoard(@RequestBody StatisticsDateQueryCondition dateQueryCondition){
        dateQueryCondition.setTimeCondition(new Date());
        List<Date> dateList = dateQueryCondition.getDayList();
        String timeSql = StatisticsDateQueryCondition.getTimeSql(dateList,"yyy-MM-dd");
        List<Date> _dateList = new ArrayList<>();
        StringBuilder timeF = new StringBuilder("yyyy-MM-dd");
        if(dateList.size() ==1){
            dateQueryCondition.setType(1);
            _dateList.addAll(DateUtils.getDay24HourList(dateList.get(0)));
            timeF.delete(0,timeF.length());
            timeF.append("yyyy-MM-dd HH");
        }else{
            _dateList.addAll(dateList);
        }
        //返回结果
        Map<String,Object> resultMap = ResultUtil.SUCCESS();

        //获取新增用户、总用户数 统计数据
        List<UserCountEntity> userCountEntityList = this.userCountEntityList(_dateList,dateQueryCondition.getType(),timeSql,timeF.toString());
        resultMap.put("userCountEntityList",userCountEntityList);

        //活跃用户数据列表
        List<ZStatisticsActiveUserCount> activeUserCountList = this.activeUserCountList(_dateList,timeSql,timeF.toString());
        resultMap.put("activeUserCountList",activeUserCountList);

        //付款用户统计列表
        List<ZStatisticsOrderBaseCount> payUserCountList = this.payUserCountList(_dateList,dateQueryCondition.getType(),timeSql,timeF.toString());
        resultMap.put("payUserCountList",payUserCountList);

        resultMap.put("type",dateQueryCondition.getType());

        //新增用户
        int regUserCount = userCountEntityList.stream().mapToInt(UserCountEntity::getRegUserNum).sum();
        resultMap.put("regUserCount",regUserCount);
        //活跃用户
        int activeUserCount = activeUserCountList.stream().mapToInt(ZStatisticsActiveUserCount::getUserCount).sum();
        resultMap.put("activeUserCount",activeUserCount);
        //付费用户
        int payUserCount = payUserCountList.stream().mapToInt(ZStatisticsOrderBaseCount::getPayUserCount).sum();
        resultMap.put("payUserCount",payUserCount);
        //总用户数
        int userCount = userCountEntityList.stream().mapToInt(UserCountEntity::getUserNum).sum();
        resultMap.put("userCount",userCount);
        resultMap.put("xList",_dateList);
        return resultMap;
    }

    /**
     * 查询付款用户概况数据
     * @return Map<String,Object>
     */
    @RequestMapping("/queryPayUserCountData")
    public Map<String,Object> queryPayUserCountData(@RequestParam("date") String date){
        ZStatisticsPayUserCount payUserCount = zStatisticsPayUserCountBiz.queryPayUserCountData(DateUtils.parseDate(date,"yyyy-MM-dd"));
        return ResultUtil.SUCCESS(payUserCount);
    }

    /**
     * 查询用户注册来源统计数据
     * @return Map<String,Object>
     */
    @RequestMapping("/queryUserRegFormCountData")
    public Map<String,Object> queryUserRegFormCountData(){
        UserRegFromEntity userRegFromEntity = cusUserBiz.queryUserRegFormCountData();
        return ResultUtil.SUCCESS(userRegFromEntity);
    }
    //================================================================================
    /**
     * 获取新增用户、总用户数 统计数据
     * @param dateList 时间列表
     * @param type 类型
     * @param timeSql 时间Sql条件
     * @param timeF 时间格式
     * @return List<UserCountEntity>
     */
    private List<UserCountEntity> userCountEntityList(List<Date> dateList,int type,String timeSql,String timeF){
        List<UserCountEntity> resultList = new ArrayList<>();
        List<UserCountEntity> userCountEntityList = cusUserBiz.queryNewUserAndUserSumList(type,timeSql);
        if(ObjectUtils.isNotEmpty(userCountEntityList)){
            Map<String,UserCountEntity> userCountEntityMap = userCountEntityList.stream().collect(Collectors.toMap(e->DateUtils.format(e.getCountTime(),timeF),e->e));
            dateList.forEach(e->{
                String key = DateUtils.format(e,timeF);
                UserCountEntity countEntity = userCountEntityMap.get(key);
                if(countEntity==null){
                    countEntity = new UserCountEntity();
                    countEntity.setCountTime(e);
                }
                resultList.add(countEntity);
            });
        }else{
            dateList.forEach(e->{
                UserCountEntity countEntity = new UserCountEntity();
                countEntity.setCountTime(e);
                resultList.add(countEntity);
            });
        }
        return resultList;
    }

    /**
     * 获取活跃用户统计数据
     * @param dateList 时间列表
     * @param timeSql 时间Sql条件
     * @param timeF 时间格式
     * @return List<ZStatisticsActiveUserCount>
     */
    private List<ZStatisticsActiveUserCount> activeUserCountList(List<Date> dateList,String timeSql,String timeF){
        List<ZStatisticsActiveUserCount> resultList =new ArrayList<>();
        List<ZStatisticsActiveUserCount> activeUserCountList = zStatisticsActiveUserCountBiz.find("countTime in "+timeSql,null,null);
        if(ObjectUtils.isNotEmpty(activeUserCountList)){
            Map<String,ZStatisticsActiveUserCount> activeUserCountMap = activeUserCountList.stream().collect(Collectors.toMap(e->DateUtils.format(e.getCountTime(),timeF),e->e));
            dateList.forEach(e->{
                String key = DateUtils.format(e,timeF);
                ZStatisticsActiveUserCount activeUserCount = activeUserCountMap.get(key);
                if(activeUserCount==null){
                    activeUserCount = new ZStatisticsActiveUserCount();
                    activeUserCount.setCountTime(e);
                }
                resultList.add(activeUserCount);
            });
        }else{
            dateList.forEach(e->{
                ZStatisticsActiveUserCount activeUserCount = new ZStatisticsActiveUserCount();
                activeUserCount.setCountTime(e);
                resultList.add(activeUserCount);
            });
        }
        return resultList;
    }

    /**
     * 获取活跃用户统计数据
     * @param dateList 时间列表
     * @param type 时间类型
     * @param timeSql 时间Sql条件
     * @param timeF 时间格式
     * @return List<ZStatisticsActiveUserCount>
     */
    private List<ZStatisticsOrderBaseCount> payUserCountList(List<Date> dateList,int type,String timeSql,String timeF){
        List<ZStatisticsOrderBaseCount> resultList = new ArrayList<>();
        List<ZStatisticsOrderBaseCount> payUserCountList = orderBiz.queryOrderPayUserCountList(type,timeSql);
        if(ObjectUtils.isNotEmpty(payUserCountList)){
            Map<String,ZStatisticsOrderBaseCount> orderBaseCountMap = payUserCountList.stream().collect(Collectors.toMap(e->DateUtils.format(e.getCountTime(),timeF),e->e));
            dateList.forEach(e->{
                String key = DateUtils.format(e,timeF);
                ZStatisticsOrderBaseCount orderBaseCount = orderBaseCountMap.get(key);
                if(orderBaseCount==null){
                    orderBaseCount = new ZStatisticsOrderBaseCount();
                    orderBaseCount.setCountTime(e);
                }
                resultList.add(orderBaseCount);
            });
        }else{
            dateList.forEach(e->{
                ZStatisticsOrderBaseCount orderBaseCount = new ZStatisticsOrderBaseCount();
                orderBaseCount.setCountTime(e);
                resultList.add(orderBaseCount);
            });
        }
        return resultList;
    }
}
